/*
 * Esta clase debe contener los metodo insert, delete, update y Find conectados a la Interfase.
 * Para ello extiende como super clase Beans, que contiende todos los atributos de la tabla
 * De requerirse algun atributo que no lo contemple Beas, este debe ser creado aquÃ­
 * 
 */
package user.login;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.el.ELContext;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import system.general.Exc;
import system.general.Logged;
import system.general.Message;
import system.general.Persistencia;
import system.general.Cryptography;

/**
 *
 * @author emojica
 */
@ManagedBean(name = "user_login")
@RequestScoped
public class Main extends Beans {
    
    Logged logged;
    private Persistencia persistencia = new Persistencia();
    private Cryptography crypto = new Cryptography();
    private Message msg = new Message();
    private user.login.Find person_generalFind = new user.login.Find();
    private List<Beans> user_loginList = new ArrayList<>();
    private Find person_userFind = new Find();
    private List<Beans> person_userList = new ArrayList<>();
    private String sql;
    private Map<String, String> map = new LinkedHashMap<>();
    private company.general.Find Find_company = new company.general.Find();
    
    public Main() {
        ELContext elContext = FacesContext.getCurrentInstance().getELContext();
        logged = (Logged) FacesContext.getCurrentInstance().getApplication().getELResolver().getValue(elContext, null, "logged");
        //namePackage();
        load();
    }

    /**
     * MÃ©todo utilizado para desplegar la informaciÃ³n de un resitro que ha
     * sido seleccionado. Para ello requiere que el id del registro haya sido
     * asignado a la variable RecordId del logged. En este caso particular, el
     * usuario es localizado por el id_persona.
     */
    private void load() {
        try {
            //Verifica si hay un registro seleccionado
            if (logged.getLoggedRol() == 0) {
                return;
            }
            
            map.clear();
            if (logged.getMasterId() == 0) {
                map.put("id = " + logged.getLoggedId(), " ");
            } else {
                map.put("id = " + logged.getMasterId(), " ");
            }
            
            person_userList.clear();
            person_userList = person_userFind.byMap(map);
            if (person_userList.isEmpty()) {
                return;
            }
            setNombre(person_userList.get(0).getNombre());
            setApellido(person_userList.get(0).getApellido());
            setUsuario(person_userList.get(0).getUsuario());
            setClave(person_userList.get(0).getClave());
            setId_compañia(person_userList.get(0).getId_compañia());
            setIdl_rol(person_userList.get(0).getIdl_rol());
            setLogin(person_userList.get(0).getLogin());
            setUnLogin(person_userList.get(0).getUnLogin());
            setRegistrado(person_userList.get(0).getRegistrado());
            setActivo(person_userList.get(0).getActivo());
            
        } catch (Exc ex) {
            msg.showMsg(namePackage(), "system", ex.getIdError());
        } catch (SQLException ex) {
            msg.showErr(namePackage(), "sql", ex);
        } catch (Exception ex) {
            msg.showErr(namePackage(), "java", ex);
        } finally {
        }
    }

    /**
     * MÃ©todo utilizado para INSERTAR O ACTUALIZAR un registro. Para ello
     * requiere que el id del registro haya sido asignado a la variable RecordId
     * del logged. En este caso en particular, el usuario es localizado por el
     * id_persona.
     */
    public void insert() {
        try {
            
            if (logged.getLoggedId() == 0) {
                throw new Exc("m4");
            }
            
            if (logged.getLoggedRol() == 2 & getIdl_rol() == 1) {
                throw new Exc("m24");
            }
            
            map.clear();
            
            map.put("usuario= '" + this.getUsuario() + "'", "   ");
            
            if (person_userFind.byExist(map)) {
                throw new Exc("m22");
            }
            
            if (logged.getLoggedRol() == 2 & getIdl_rol() == 2) {
                if (person_userFind.verificarUser()) {
                    throw new Exc("m25");
                }
            }
            
            sql = "INSERT INTO public.usuarios "
                    + "(nombre, apellido,usuario,clave,id_compania,idl_rol,unlogin,login,registrado,activo) "
                    + "VALUES ("
                    + "'" + getNombre() + "',"
                    + "'" + getApellido() + "',"
                    + "'" + getUsuario() + "', "
                    + "'" + crypto.encryption(getClave()) + "', "
                    + getId_compañia() + ", "
                    + getIdl_rol() + " ,"
                    + "CURRENT_TIMESTAMP, "
                    + "CURRENT_TIMESTAMP, "
                    + "CURRENT_TIMESTAMP, "
                    + " '" + getActivo() + "')";

            //Inserta la informaciÃ³n del registro
            persistencia.executeUpdate(sql);
            //Localiza el id_persona a traves de dni (llave unica)
            person_userList = person_userFind.byMap(map);

            //Actualiza el logged con el ID del registro recien insertado            
            logged.setMasterId(person_userList.get(0).getId());
            logged.setMasterName(person_userList.get(0).getNombre() + " " + person_userList.get(0).getApellido());
            throw new Exc("m1");
        } catch (Exc ex) {
            msg.showMsg(namePackage(), "system", ex.getIdError());
        } catch (SQLException ex) {
            msg.showErr(namePackage(), "sql", ex);
        } catch (Exception ex) {
            msg.showErr(namePackage(), "java", ex);
        } finally {
        }
    }
    
    public void update() {
        try {
            
            if (logged.getMasterId() == 0) {
                this.setId(logged.getLoggedId());
            } else {
                this.setId(logged.getMasterId());
            }
            
            
            if (logged.getLoggedRol() == 2 & getIdl_rol() == 1) {
                throw new Exc("m24");
            }
            
            
            
            map.clear();
            map.put(" id <> " + this.getId(), " AND ");
            map.put(" nombre = '" + this.getNombre() + "'", "  AND ");
            map.put(" apellido = '" + this.getApellido() + "'", "  AND ");
            map.put(" usuario = '" + this.getUsuario() + "'", "  AND ");
            map.put(" clave = '" + crypto.encryption(this.getClave()) + "'", "  AND ");
            map.put(" id_compania=" + this.getId_compañia(), "  AND ");
            map.put(" idl_rol =" + this.getIdl_rol(), "   ");
            if (person_userFind.byExist(map)) {
                throw new Exc("m22");
            }
            sql = "UPDATE public.usuarios SET "
                    + "nombre = '" + getNombre() + "',  "
                    + "apellido = '" + getApellido() + "',  "
                    + "usuario = '" + getUsuario() + "',  "
                    + "clave = '" + crypto.encryption(getClave()) + "', "
                    + "id_compania  = " + getId_compañia() + ", "
                    + "idl_rol = " + getIdl_rol() + ", "
                    + "activo = '" + getActivo() + "'  "
                    + "WHERE id =" + this.getId();

            //Actualiza la informaciÃ³n del registro
            persistencia.executeUpdate(sql);
            // si es el usuario que inicio sesion 
            if (logged.getLoggedId() == this.getId()) {
                logged.setLoggedName(this.getNombre() + " " + this.getApellido());
                logged.setLoggedRol(this.getIdl_rol());
                logged.clearMenu();
            }
            
            throw new Exc("m2");
        } catch (Exc ex) {
            msg.showMsg(namePackage(), "system", ex.getIdError());
        } catch (SQLException ex) {
            msg.showErr(namePackage(), "sql", ex);
        } catch (Exception ex) {
            msg.showErr(namePackage(), "java", ex);
        } finally {
        }
    }
    
    public void delete() {
        try {

            //Verifica si hay registros seleccionados
            if (logged.getMasterId() == 0) {
                throw new Exc("m4");
            }

            //Elimina el resgistro por el id_persona
            deleteByIdPersona(logged.getMasterId());
            
            throw new Exc("m3");
            
        } catch (Exc ex) {
            msg.showMsg(namePackage(), "system", ex.getIdError());
        } catch (SQLException ex) {
            msg.showErr(namePackage(), "sql", ex);
        } catch (Exception ex) {
            msg.showErr(namePackage(), "java", ex);
        } finally {
        }
    }
    
    public String login() {
        try {

            //Consulta si el usuario y clave existen
            map.clear();
            map.put("lower(usuario) = '" + getUsuario().toLowerCase(), "' AND ");
            map.put("clave = '" + crypto.encryption(getClave()), "' AND ");
            map.put("activo = 'TRUE" ,"' ");
            person_userList = person_userFind.byMap(map);
            if (person_userList.isEmpty()) {
                throw new Exc("m21");
            }
            //Consulta la informaciÃ³n de la persona
            map.clear();
            map.put("id = " + person_userList.get(0).getId(), " ");
            user_loginList = person_generalFind.byMap(map);

            //logged.clear();
            logged.setLoggedId(user_loginList.get(0).getId());
            logged.setMasterId(user_loginList.get(0).getId());
            logged.setLoggedName(user_loginList.get(0).getNombre() + " " + user_loginList.get(0).getApellido());
            logged.setMasterName(user_loginList.get(0).getUsuario());
            logged.setDetailId(user_loginList.get(0).getId_compañia());
            logged.setLoggedRol(user_loginList.get(0).getIdl_rol());
            //Actualiza la fecha y hora del login
            //loginDate();
            return "/faces/test.xhtml?faces-redirect=true";
            
        } catch (Exc ex) {
            msg.showMsg(namePackage(), "system", ex.getIdError());
            return "/faces/home.xhtml";
        } catch (SQLException ex) {
            msg.showErr(namePackage(), "sql", ex);
            return "/faces/home.xhtml";
        } catch (Exception ex) {
            msg.showErr(namePackage(), "java", ex);
            return "/faces/home.xhtml";
        } finally {
        }
    }
    
    public String unLogin() throws Throwable {
        //Actualiza la fecha y hora de cerrar session
        unLoginDate();
        logged.clearAll();
        return "/faces/home.xhtml";
        
    }
    
    public void loginDate() {
        try {
            sql = "UPDATE public.usuarios SET "
                    + "login = CURRENT_TIMESTAMP "
                    + "WHERE id =" + logged.getLoggedId();

            //Actualiza la informaciÃ³n del registro
            persistencia.executeUpdate(sql);
            
        } catch (Exc ex) {
            msg.showMsg(namePackage(), "system", ex.getIdError());
        } catch (SQLException ex) {
            msg.showErr(namePackage(), "sql", ex);
        } catch (Exception ex) {
            msg.showErr(namePackage(), "java", ex);
        } finally {
        }
    }
    
    public void unLoginDate() {
        try {
            sql = "UPDATE public.usuarios SET "
                    + "unlogin = CURRENT_TIMESTAMP "
                    + "WHERE id =" + logged.getLoggedId();

            //Actualiza la informaciÃ³n del registro
            persistencia.executeUpdate(sql);
            
        } catch (Exc ex) {
            msg.showMsg(namePackage(), "system", ex.getIdError());
        } catch (SQLException ex) {
            msg.showErr(namePackage(), "sql", ex);
        } catch (Exception ex) {
            msg.showErr(namePackage(), "java", ex);
        } finally {
        }
    }
    
    public List<SelectItem> getcompanyItemList() {
        map.clear();
        // Para que me traiga toda la lista de compañias 
        map.put("id <>  0 ", " ");
        try {
            return Find_company.listItem(map);
        } catch (Exc ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }
    
    public void deleteByIdUsuario(int id) throws Exc, SQLException, Exception {
        //Verifica si el usuario ya existe para otra persona
        sql = "DELETE FROM public.usuarios "
                + "WHERE id = " + id;
        persistencia.executeUpdate(sql);
    }
    
    public void deleteByIdPersona(int id) throws Exc, SQLException, Exception {
        //Verifica si el usuario ya existe para otra persona
        sql = "DELETE FROM public.usuarios "
                + "WHERE id = " + id;
        persistencia.executeUpdate(sql);
    }
    
    public void restartKey() {
        try {
            //Verifica si hay registros seleccionados
            if (logged.getMasterId() != 0) {
                throw new Exc("m2");
            }
            sql = "UPDATE public.usuarios SET "
                    + "clave = '" + crypto.encryption("12345") + "' "
                    + "WHERE id =" + logged.getMasterId();

            //Actualiza la informaciÃ³n del registro seleccionado
            persistencia.executeUpdate(sql);
            
            throw new Exc("m2");
            
        } catch (Exc ex) {
            msg.showMsg(namePackage(), "system", ex.getIdError());
        } catch (SQLException ex) {
            msg.showErr(namePackage(), "sql", ex);
        } catch (Exception ex) {
            msg.showErr(namePackage(), "java", ex);
        } finally {
        }
    }
    
    public void clear() {
        logged.setMasterId(0);
        clearBeans();
    }
    
    private String namePackage() {
        Package pack = this.getClass().getPackage();
        return pack.getName();
    }
    
    public boolean acceso() {
        if (logged.getLoggedRol() == 1) {
            return false;
        }
        return true;
        
    }
    
    public boolean accesoUpdate() {
        if (logged.getLoggedRol() == 1 | logged.getLoggedRol() == 2) {
            return false;
        }
        return true;
        
    }
    
    public boolean accesoRendered() {
        if (logged.getLoggedRol() == 1 | logged.getLoggedRol() == 2) {
            return true;
        }
        return false;
        
    }
}
